package com.cuanbo.dualscreenteachfu.utils;

import android.content.Context;

import com.cuanbo.dualscreenteachfu.bean.FileBean;
import com.cuanbo.dualscreenteachfu.constant.FileConstant;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;

/**
 * 文件工具类
 */
public class FileUtil {
    /**
     * 只获取文件
     */
    public static final int ONLY_FILE = 1;
    /**
     * 只获取文件夹
     */
    public static final int ONLY_DIR = 2;
    /**
     * 获取文件和文件夹
     */
    public static final int ALL = 3;

    /**
     * 将数据写入文件中
     *
     * @param context        上下文对象
     * @param strData        要保存到文件中的字符串数据
     * @param savePath       保存路径
     * @param resultListener 结果监听器
     */
    public static void writeDataToFile(Context context, final String strData, final String savePath, final ResultListener resultListener) {
        final File f = new File(savePath);
        LogUtil.add("保存路径", savePath, "写入文件日志");
        LogUtil.add("数据内容", strData, "写入文件日志");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(
                                    new FileOutputStream(f, false), "GBK"));
                    writer.write(strData);
                    writer.flush();
                    writer.close();
                    if (resultListener != null) {
                        resultListener.success();
                    }
                } catch (Exception e) {
                    LogUtil.addError("-------将数据写入文件时异常--------");
                    LogUtil.addError("保存路径:" + savePath);
                    LogUtil.addError("数据内容:" + strData);
                    LogUtil.addError(e);
                    if (resultListener != null) {
                        resultListener.fail("保存失败，错误:" + e.getMessage());
                    }
                }
            }
        }).start();
    }

    public interface ResultListener {
        void fail(String msg);

        void success();
    }

    /**
     * 从文件中读取数据
     *
     * @param context 上下文对象
     * @param path    文件路径
     */
    public static String readDataFromFile(Context context, String path) {
        LogUtil.add("保存路径", path, "读取文件日志");
        File f = new File(path);
        if (f.exists() && f.isFile()) {
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "GBK"));
                String strData = reader.readLine();
                reader.close();
                LogUtil.add("读取内容", strData, "读取文件日志");
                return strData;
            } catch (Exception e) {
                LogUtil.addError("-------读取文件中数据时异常--------");
                LogUtil.addError("保存路径:" + path);
                LogUtil.addError(e);
            }
        } else {
            ToastUtil.show(context, "错误:文件不存在或者不是文件！");
            return null;
        }
        return null;
    }

    /**
     * 获取该文件夹中的文件夹和文件
     *
     * @param dir  文件夹
     * @param type 要获取的类型ONLY_FILE、ONLY_DIR、ALL
     */
    public static ArrayList<FileBean> getAllFiles(File dir, int type) {
        ArrayList<FileBean> fileBeans = null;
        try {
            if (dir.isDirectory()) {
                fileBeans = new ArrayList<>();
                File[] files = dir.listFiles();
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isDirectory()) {//是文件夹
                        if (type == FileUtil.ALL || type == FileUtil.ONLY_DIR) {
                            fileBeans.add(new FileBean(files[i].getName(), FileConstant.TYPE_DIR, files[i].getAbsolutePath()));
                        }
                    } else {//是文件
                        if (type == FileUtil.ALL || type == FileUtil.ONLY_FILE) {
                            fileBeans.add(new FileBean(files[i].getName(), FileConstant.TYPE_FILE, files[i].getAbsolutePath()));
                        }
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.addError("-------获取文件夹中的所有文件和文件夹时异常--------");
            LogUtil.addError("文件夹路径:" + dir.getAbsolutePath());
            LogUtil.addError(e);
        }
        return fileBeans;
    }

    /**
     * 获取所有文件
     *
     * @param str  文件路径
     * @param type 文件类型
     * @return 文件集合类
     */
    public static ArrayList<FileBean> getAllFiles(String str, int type) {
        return getAllFiles(new File(str), type);
    }

    /**
     * 获取文件或文件夹的大小
     *
     * @param file 文件或文件夹对象
     * @return 返回文件或文件夹的大小
     */
    public static long getFileSize(final File file) {
        if (file == null) return 0;
        if (file.isFile()) return file.length();
        final File[] children = file.listFiles();
        long total = 0;
        if (children != null)
            for (final File child : children)
                total += getFileSize(child);
        return total;
    }

    /**
     * 删除文件或文件夹
     *
     * @param file 文件或文件夹对象
     * @return 删除是否成功
     */
    public static boolean deleteAllFile(File file) {
        if (file == null || !file.exists()) return false;
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                deleteAllFile(f);
            } else {
                f.delete();
            }
        }
        file.delete();
        return true;
    }

    /**
     * 检查清空文件夹
     *
     * @param dir              文件夹的路径
     * @param allowMaxFileSize 文件夹储存上限
     */
    public static void checkClearDir(String dir, int allowMaxFileSize) {
        File fDir = new File(dir);
        if (FileUtil.getFileSize(fDir) > allowMaxFileSize * 1024 * 1024l) {//当数据超过上限时,清空日志文件夹重新写入数据
            FileUtil.deleteAllFile(fDir);
            LogUtil.add("清空文件夹", dir, "文件管理");
        }

    }

    public static void copy(String sourcePath, String destPath){
        InputStream input = null;
        OutputStream output = null;
        LogUtil.add("","开始复制文件","文件");
        LogUtil.add("源地址",""+sourcePath,"文件");
        LogUtil.add("目标地址",""+destPath,"文件");
        try {
            input = new FileInputStream(sourcePath);
            output = new FileOutputStream(destPath);
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, bytesRead);
            }
            LogUtil.add("","文件复制成功!","文件");
        } catch (Exception e) {
            LogUtil.addError("==================文件复制失败===================");
            LogUtil.addError(e);
            LogUtil.addError("=====================================");
        } finally {
            try{
                input.close();
                output.close();
            }catch (Exception e){}
        }
    }

    public static void copy(InputStream input, String destPath){
        OutputStream output = null;
        LogUtil.add("","开始复制文件","文件",true);
        LogUtil.add("输入流",""+input,"文件",true);
        LogUtil.add("目标地址",""+destPath,"文件",true);
        try {
            output = new FileOutputStream(destPath);
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, bytesRead);
            }
            LogUtil.add("","文件复制成功!","文件",true);
        } catch (Exception e) {
            LogUtil.addError("==================文件复制失败===================");
            LogUtil.addError(e);
            LogUtil.addError("=====================================");
        } finally {
            try{
                input.close();
                output.close();
            }catch (Exception e){}
        }
    }
}
